import os, sys
from socket import *
from threading import Thread
import time

HOST = '0.0.0.0'
PORT = 8080
ADDR = (HOST, PORT)
FILE_DIR = '/Users/mayewei/Desktop/information/code/'

def zombie():
    os.wait()

class FtpServer(object):
    def __init__(self, connfd):
        self.connfd = connfd
    
    def do_list(self):
        file_list = os.listdir(FILE_DIR)
        if not file_list:
            self.connfd.send('file_database is empty!')
            return
        else:
            self.connfd.send(b'OK')
            time.sleep(0.1)
        for file in file_list:
            if file[0] != '.':
                self.connfd.send(file.encode())
                time.sleep(0.1)
        self.connfd.send(b'##')
    
    def do_get(self, filename):
        try:
            fd = open(FILE_DIR+filename, 'rb')
        except:
            self.connfd.send('file not exist!'.encode())
            return
        else:
            self.connfd.send(b'OK')
            time.sleep(0.1)
        while True:
            data = fd.read(1024)
            if not data:
                time.sleep(0.1)
                self.connfd.send(b'##')
                break
            self.connfd.send(data)
        fd.close()
    
    def do_put(self, filename):
        try:
            f = open(FILE_DIR + filename, 'wb')
        except:
            self.connfd.send('Transfer failed!')
        else:
            self.connfd.send(b'OK')
        while True:
            data = self.connfd.recv(1024)
            if data == b'##':
                break
            f.write(data)
        f.close()

def main():
    sockfd = socket()
    sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    sockfd.bind(ADDR)
    sockfd.listen(5)
    print('Listen to the port 8080...')

    while True:
        try:
            connfd, addr = sockfd.accept()
        except KeyboardInterrupt:
            sockfd.close()
            sys.exit('quit the server')
        except Exception as e:
            print('There is a error on server', e)
        print('Connect the client:', addr)

        pid = os.fork()
        if pid == 0:
            sockfd.close()
            ftp = FtpServer(connfd)
            while True:
                data = connfd.recv(1024).decode()
                if not data or data[0] == 'Q':
                    connfd.close()
                    sys.exit('Server quit')
                elif data[0] == 'L':
                    ftp.do_list()
                elif data[0] == 'G':
                    filename = data.split(' ')[-1]
                    ftp.do_get(filename)
                elif data[0] == 'P':
                    filename = data.split(' ')[-1]
                    ftp.do_put(filename)
                
            os._exit(0)
        else:
            connfd.close()
            t = Thread(target=zombie)
            t.setDaemon(True)
            t.start()
            continue


main()